package com.fulihui.usercore.service;

import com.fulihui.usercore.api.UserWechatService;
import com.fulihui.usercore.biz.shard.WechatUserManager;
import com.fulihui.usercore.common.util.AppProps;
import com.fulihui.usercore.core.repository.*;
import com.fulihui.usercore.dal.dataobj.LoginDO;
import com.fulihui.usercore.dal.dataobj.WechatOpenidHelpDOExample;
import com.fulihui.usercore.dal.dataobj.WechatUnionidHelpDOExample;
import com.fulihui.usercore.dal.dataobj.WechatUserExample;
import com.fulihui.usercore.dto.WechatUserDTO;
import com.fulihui.usercore.enums.WechatOpenIdTypeEnum;
import com.fulihui.usercore.request.user.UserIdRequest;
import com.fulihui.usercore.request.user.UserLoginIdWechatRequest;
import com.fulihui.usercore.request.wechat.BindingWechatRequest;
import com.fulihui.usercore.request.wechat.UserWechatQueryByTypeRequest;
import com.fulihui.usercore.request.wechat.UserWechatQueryRequest;
import org.apache.dubbo.config.annotation.Service;
import org.near.servicesupport.result.BaseResult;
import org.near.servicesupport.result.ResultBuilder;
import org.near.servicesupport.result.TMultiResult;
import org.near.servicesupport.result.TSingleResult;

import org.near.servicesupport.util.ServiceAssert;
import org.near.toolkit.common.EnumUtil;
import org.near.toolkit.common.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.List;

import static org.near.servicesupport.error.Errors.Commons.REQUEST_PARAMETER_ERROR;
import static org.near.servicesupport.result.ResultBuilder.*;
import static org.near.servicesupport.util.ServiceAssert.isTrue;
import static org.near.toolkit.common.EnumUtil.inEnum;
import static org.springframework.util.CollectionUtils.isEmpty;

/**
 * @author Willard.Hu on 2016/12/15 0015.
 */
@Service(version = "1.0.0")
public class UserWechatServiceImpl implements UserWechatService {
    @Autowired
    private WechatUserRepository wechatUserRepository;
    @Autowired
    private WechatUserManager wechatUserManager;
    @Autowired
    private UserLoginRepository userLoginRepository;
    @Autowired
    private WechatUnionidHelpRepository wechatUnionidHelpRepository;
    @Autowired
    private WechatOpenidHelpRepository wechatOpenidHelpRepository;
    @Autowired
    private LoginHelpRepository loginHelpRepository;
    @Autowired
    AppProps appProps;

    /**
     * @see UserWechatService#querySingle(UserWechatQueryRequest)
     */
    @Override
    public TSingleResult<WechatUserDTO> querySingle(UserWechatQueryRequest request) {
        isTrue(hasNotBlank(request.getOpenId(), request.getUnionid(), request.getUserId()), REQUEST_PARAMETER_ERROR);
        List<WechatUserDTO> list = null;

        if (StringUtil.isNotBlank(request.getUserId())) {
            WechatUserExample example = new WechatUserExample();
            WechatUserExample.Criteria criteria = example.createCriteria();
            criteria.andAppidEqualTo(request.getAppid());
            criteria.andUserIdEqualTo(request.getUserId());
            criteria.andDisableEqualTo(0);
            list = wechatUserRepository.query(example);
        }
        if (StringUtil.isNotBlank(request.getOpenId())) {
            WechatOpenidHelpDOExample example = new WechatOpenidHelpDOExample();
            WechatOpenidHelpDOExample.Criteria criteria = example.createCriteria();
            criteria.andAppidEqualTo(request.getAppid());
            criteria.andOpenIdEqualTo(request.getOpenId());
            list = wechatOpenidHelpRepository.query(example);
        }
        if (StringUtil.isNotBlank(request.getUnionid())) {
            WechatUnionidHelpDOExample example = new WechatUnionidHelpDOExample();
            WechatUnionidHelpDOExample.Criteria criteria = example.createCriteria();
            criteria.andAppidEqualTo(request.getAppid());
            criteria.andUnionidEqualTo(request.getUnionid());
            list = wechatUnionidHelpRepository.query(example);
        }
        // 集合不为空获取第一个
        return succTSingle(isEmpty(list) ? null : list.get(0));
    }

    private boolean hasNotBlank(String... strs) {
        if (strs != null) {
            for (String s : strs) {
                if (StringUtil.isNotBlank(s)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 检查 openidType 类型是否合法，并且检查appid是否有值，
     * 没有值的话，通过openidType获取默认值
     *
     * @param appid      微信平台标识
     * @param openidType openid类型，APP / MP
     * @return appid有值，直接返回appid，否则通过openidType获取默认的appid
     */
    private String checkOpenidTypeAndGetDefaultAppidIfNil(String appid, String openidType) {
        if (StringUtil.isBlank(appid)) {
            if (WechatOpenIdTypeEnum.WECHAT_MP.getCode().equals(openidType)) {
                appid = appProps.getWechatMpAppid();
            } else if (WechatOpenIdTypeEnum.NATIVE_APP.getCode().equals(openidType)) {
                appid = appProps.getWechatAppAppid();
            } else {
                throw new IllegalArgumentException("非法的openidType:" + openidType);
            }
        } else {
            Assert.isTrue(EnumUtil.inEnum(openidType, WechatOpenIdTypeEnum.class),
                    "非法的openidType:" + openidType);
        }
        return appid;
    }

    /**
     * @see UserWechatService#bindingWechat(BindingWechatRequest)
     */
    @Override
    public BaseResult bindingWechat(BindingWechatRequest request) {
        isTrue(inEnum(request.getOpenIdType(), WechatOpenIdTypeEnum.class), REQUEST_PARAMETER_ERROR);
        WechatUserDTO record = new WechatUserDTO();
        record.setAppid(request.getAppid());
        record.setOpenId(request.getOpenId());
        record.setOpenidType(request.getOpenIdType());
        record.setUnionid(request.getUnionid());
        record.setUserId(request.getUserId());
        wechatUserManager.bindingByUserId(record);
        return succ(BaseResult.class);
    }

    /**
     * @see UserWechatService#userBounds(UserIdRequest)
     */
    @Override
    public TMultiResult<WechatUserDTO> userBounds(UserIdRequest request) {
        WechatUserExample example = new WechatUserExample();
        example.createCriteria().andUserIdEqualTo(request.getUserId());
        List<WechatUserDTO> list = wechatUserRepository.query(example);
        return succTMulti(list);
    }

    @Override
    public TSingleResult<Boolean> isBindingNativeApp(UserLoginIdWechatRequest request) {

        //根据loginId查询userId
        LoginDO loginDO = loginHelpRepository.queryByPK(request.getLoginId());
        if (loginDO == null) {
            return ResultBuilder.failTSingle(401, "根据手机号查询userId有误！");
        }
        UserIdRequest userIdRequest = new UserIdRequest();
        userIdRequest.setUserId(loginDO.getUserId());
        TMultiResult<WechatUserDTO> result = this.userBounds(userIdRequest);
        if (!CollectionUtils.isEmpty(result.getValues())) {
            List<WechatUserDTO> values = result.getValues();
            for (WechatUserDTO wechatUserDTO : values) {
                if (StringUtil.equals(WechatOpenIdTypeEnum.NATIVE_APP.getCode(), wechatUserDTO.getOpenidType())) {
                    return ResultBuilder.succTSingle(Boolean.TRUE);
                }
            }
        }
        return ResultBuilder.succTSingle(Boolean.FALSE);
    }

    /**
     * 耳朵提现查询openid
     *
     * @param request
     * @return
     */
    @Override
    public TSingleResult<WechatUserDTO> queryOpenId(UserWechatQueryRequest request) {
        //step1: 根据userid查询unionid
        WechatUserExample example = new WechatUserExample();
        example.createCriteria()
                .andUserIdEqualTo(request.getUserId())
                .andOpenidTypeEqualTo(WechatOpenIdTypeEnum.NATIVE_APP.getCode())
                .andDisableEqualTo(0);
        List<WechatUserDTO> list = wechatUserRepository.query(example);
        if (CollectionUtils.isEmpty(list)) {
            return succTSingle(null);
        }

        //step2: 根据unionid查询openid
        WechatUserDTO wechatUserDTO = list.get(0);
        String unionid = wechatUserDTO.getUnionid();
        WechatUnionidHelpDOExample unionidExample = new WechatUnionidHelpDOExample();

        unionidExample.createCriteria()
                .andUnionidEqualTo(unionid)
                .andOpenidTypeEqualTo(WechatOpenIdTypeEnum.WECHAT_MP.getCode());
        List<WechatUserDTO> wechatList = wechatUnionidHelpRepository.query(unionidExample);
        return succTSingle(isEmpty(wechatList) ? null : wechatList.get(0));
    }

    @Override
    public TSingleResult<WechatUserDTO> querySingleByOpenIdAndType(UserWechatQueryByTypeRequest request) {
        ServiceAssert.isTrue(inEnum(request.getOpenIdType(), WechatOpenIdTypeEnum.class),
                REQUEST_PARAMETER_ERROR);
        WechatOpenidHelpDOExample example = new WechatOpenidHelpDOExample();
        WechatOpenidHelpDOExample.Criteria criteria = example.createCriteria();
        criteria.andOpenIdEqualTo(request.getOpenId());
        criteria.andAppidEqualTo(checkOpenidTypeAndGetDefaultAppidIfNil("", request.getOpenIdType()));
        List<WechatUserDTO> list = wechatOpenidHelpRepository.query(example);
        // 集合不为空获取第一个
        return succTSingle(isEmpty(list) ? null : list.get(0));
    }
}
